agora inbox for [email protected]  
help / color / mirror / Atom feed
Bug in current network.c
814+ messages / 4 participants
[nested] [flat]

* Bug in current network.c
@ 1998-10-29 10:09  Andreas Zeugswetter <[email protected]>
  0 siblings, 1 reply; 814+ messages in thread

From: Andreas Zeugswetter @ 1998-10-29 10:09 UTC (permalink / raw)
  To: '[email protected]' <[email protected]>


The network.c from current CVS has:

xlc -I../../../include -I../../../backend   -I/usr/local/include 
-qchars=signed -qmaxmem=8192 -qhalt=w -qsrcmsg -qcheck=divzero -qlonglong 
 -g -qfullpath -I../..   -c network.c -o network.o
      400 |                 if (inet_cidr_ntop(2, &addr, (((inet_struct 
*)(((struct varlena *)(ip))->vl_dat))->bits), tmp, sizeof(tmp)) < 0)
 
           .............................................................  
...............................................................a...
a - 1506-068 (S) Operation between types "char*" and "int" is not allowed.
gmake[3]: *** [network.o] Error 1

It should probably read as follows: (but please check)
(I sure hope it comes without those stupid wraps my mailer always 
generates)

*** network.c.ori	Thu Oct 29 09:51:42 1998
--- network.c	Thu Oct 29 10:35:59 1998
***************
*** 397,403 ****
  		/* It's an IP V4 address: */
  		int	addr = htonl(ntohl(ip_v4addr(ip)) & (0xffffffff << (32 - 
ip_bits(ip))));

! 		if (inet_cidr_ntop(AF_INET, &addr, ip_bits(ip), tmp, sizeof(tmp)) < 0)
  		{
  			elog(ERROR, "unable to print network (%s)", strerror(errno));
  			return (NULL);
--- 397,403 ----
  		/* It's an IP V4 address: */
  		int	addr = htonl(ntohl(ip_v4addr(ip)) & (0xffffffff << (32 - 
ip_bits(ip))));

! 		if (inet_cidr_ntop(AF_INET, &addr, ip_bits(ip), tmp, sizeof(tmp)) == 
NULL)
  		{
  			elog(ERROR, "unable to print network (%s)", strerror(errno));
  			return (NULL);


Attached is also a correct inet.out

 

begin 600 inet.out
M455%4EDZ($123U @5$%"3$4@24Y%5%]40DP["D524D]2.B @4F5L871I;VX@
M:6YE=%]T8FP@1&]E<R!.;W0@17AI<W0A"E%515)9.B!#4D5!5$4@5$%"3$4@
M24Y%5%]40DP@*&,@8VED<BP@:2!I;F5T*3L*455%4EDZ($E.4T525"!)3E1/
M($E.151?5$),("AC+"!I*2!604Q515,@*"<Q.3(N,38X+C$G+" G,3DR+C$V
M."XQ+C(R-B\R-"<I.PI1545263H@24Y315)4($E.5$\@24Y%5%]40DP@*&,L
M(&DI(%9!3%5%4R H)S$Y,BXQ-C@N,2XR+S(T)RP@)S$Y,BXQ-C@N,2XR,C8G
M*3L*455%4EDZ($E.4T525"!)3E1/($E.151?5$),("AC+"!I*2!604Q515,@
M*"<Q,"<L("<Q,"XQ+C(N,R\X)RD["E%515)9.B!)3E-%4E0@24Y43R!)3D54
M7U1"3" H8RP@:2D@5D%,5453("@G,3 N,"XP+C G+" G,3 N,2XR+C,O."<I
M.PI1545263H@24Y315)4($E.5$\@24Y%5%]40DP@*&,L(&DI(%9!3%5%4R H
M)S$P+C$N,BXS)RP@)S$P+C$N,BXS+S,R)RD["E%515)9.B!)3E-%4E0@24Y4
M3R!)3D547U1"3" H8RP@:2D@5D%,5453("@G,3 N,2XR)RP@)S$P+C$N,BXS
M+S(T)RD["E%515)9.B!)3E-%4E0@24Y43R!)3D547U1"3" H8RP@:2D@5D%,
M5453("@G,3 N,2<L("<Q,"XQ+C(N,R\Q-B<I.PI1545263H@24Y315)4($E.
M5$\@24Y%5%]40DP@*&,L(&DI(%9!3%5%4R H)S$P)RP@)S$P+C$N,BXS+S@G
M*3L*455%4EDZ(%-%3$5#5" G)R!A<R!E:6=H="P@8R!A<R!C:61R+"!I(&%S
M(&EN970@1E)/32!)3D547U1"3#L*96EG:'1\8VED<B @(" @(" @?&EN970@
M(" @(" @(" @(" *+2TM+2TK+2TM+2TM+2TM+2TM*RTM+2TM+2TM+2TM+2TM
M+2T*(" @("!\,3DR+C$V."XQ+S(T?#$Y,BXQ-C@N,2XR,C8O,C0*(" @("!\
M,3DR+C$V."XQ+S(T?#$Y,BXQ-C@N,2XR,C8@(" *(" @("!\,3 O." @(" @
M(" @?#$P+C$N,BXS+S@@(" @(" *(" @("!\,3 N,"XP+C O,S(@?#$P+C$N
M,BXS+S@@(" @(" *(" @("!\,3 N,2XR+C,O,S(@?#$P+C$N,BXS(" @(" @
M(" *(" @("!\,3 N,2XR+S(T(" @?#$P+C$N,BXS+S(T(" @(" *(" @("!\
M,3 N,2\Q-B @(" @?#$P+C$N,BXS+S$V(" @(" *(" @("!\,3 O." @(" @
M(" @?#$P+C$N,BXS+S@@(" @(" **#@@<F]W<RD*"E%515)9.B!314Q%0U0@
M)R<@87,@96EG:'0L(&D@87,@:6YE="P@:&]S="AI*2!&4D]-($E.151?5$),
M.PIE:6=H='QI;F5T(" @(" @(" @(" @?" @(" @(" @(&AO<W0*+2TM+2TK
M+2TM+2TM+2TM+2TM+2TM+2LM+2TM+2TM+2TM+2TM"B @(" @?#$Y,BXQ-C@N
M,2XR,C8O,C1\,3DR+C$V."XQ+C(R-@H@(" @('PQ.3(N,38X+C$N,C(V(" @
M?#$Y,BXQ-C@N,2XR,C8*(" @("!\,3 N,2XR+C,O." @(" @('P@(" @(#$P
M+C$N,BXS"B @(" @?#$P+C$N,BXS+S@@(" @("!\(" @(" Q,"XQ+C(N,PH@
M(" @('PQ,"XQ+C(N,R @(" @(" @?" @(" @,3 N,2XR+C,*(" @("!\,3 N
M,2XR+C,O,C0@(" @('P@(" @(#$P+C$N,BXS"B @(" @?#$P+C$N,BXS+S$V
M(" @("!\(" @(" Q,"XQ+C(N,PH@(" @('PQ,"XQ+C(N,R\X(" @(" @?" @
M(" @,3 N,2XR+C,**#@@<F]W<RD*"E%515)9.B!314Q%0U0@)R<@87,@96EG
M:'0L(&,@87,@8VED<BP@8G)O861C87-T*&,I+ H@(&D@87,@:6YE="P@8G)O
M861C87-T*&DI($923TT@24Y%5%]40DP["F5I9VAT?&-I9'(@(" @(" @('P@
M(" @(&)R;V%D8V%S='QI;F5T(" @(" @(" @(" @?" @(" @8G)O861C87-T
M"BTM+2TM*RTM+2TM+2TM+2TM+2LM+2TM+2TM+2TM+2TM+2LM+2TM+2TM+2TM
M+2TM+2TM*RTM+2TM+2TM+2TM+2TM"B @(" @?#$Y,BXQ-C@N,2\R-'P@,3DR
M+C$V."XQ+C(U-7PQ.3(N,38X+C$N,C(V+S(T?" Q.3(N,38X+C$N,C4U"B @
M(" @?#$Y,BXQ-C@N,2\R-'P@,3DR+C$V."XQ+C(U-7PQ.3(N,38X+C$N,C(V
M(" @?" Q.3(N,38X+C$N,C(V"B @(" @?#$P+S@@(" @(" @('PQ,"XR-34N
M,C4U+C(U-7PQ,"XQ+C(N,R\X(" @(" @?#$P+C(U-2XR-34N,C4U"B @(" @
M?#$P+C N,"XP+S,R('P@(" @(" Q,"XP+C N,'PQ,"XQ+C(N,R\X(" @(" @
M?#$P+C(U-2XR-34N,C4U"B @(" @?#$P+C$N,BXS+S,R('P@(" @(" Q,"XQ
M+C(N,WPQ,"XQ+C(N,R @(" @(" @?" @(" @(#$P+C$N,BXS"B @(" @?#$P
M+C$N,B\R-" @('P@(" @,3 N,2XR+C(U-7PQ,"XQ+C(N,R\R-" @(" @?" @
M(" Q,"XQ+C(N,C4U"B @(" @?#$P+C$O,38@(" @('P@(#$P+C$N,C4U+C(U
M-7PQ,"XQ+C(N,R\Q-B @(" @?" @,3 N,2XR-34N,C4U"B @(" @?#$P+S@@
M(" @(" @('PQ,"XR-34N,C4U+C(U-7PQ,"XQ+C(N,R\X(" @(" @?#$P+C(U
M-2XR-34N,C4U"B@X(')O=W,I"@I1545263H@4T5,14-4("<G(&%S(&5I9VAT
M+"!C(&%S(&-I9'(L(&YE='=O<FLH8RD@87,@(FYE='=O<FLH8VED<BDB+ H@
M(&D@87,@:6YE="P@;F5T=V]R:RAI*2!A<R B;F5T=V]R:RAI;F5T*2(@1E)/
M32!)3D547U1"3#L*96EG:'1\8VED<B @(" @(" @?&YE='=O<FLH8VED<BE\
M:6YE=" @(" @(" @(" @('QN971W;W)K*&EN970I(" @"BTM+2TM*RTM+2TM
M+2TM+2TM+2LM+2TM+2TM+2TM+2TM*RTM+2TM+2TM+2TM+2TM+2TK+2TM+2TM
M+2TM+2TM+2TM+0H@(" @('PQ.3(N,38X+C$O,C1\,3DR+C$V."XQ+S(T('PQ
M.3(N,38X+C$N,C(V+S(T?#$Y,BXQ-C@N,2\R-" @(" *(" @("!\,3DR+C$V
M."XQ+S(T?#$Y,BXQ-C@N,2\R-"!\,3DR+C$V."XQ+C(R-B @('PQ.3(N,38X
M+C$N,C(V+S,R"B @(" @?#$P+S@@(" @(" @('PQ,"\X(" @(" @(" @?#$P
M+C$N,BXS+S@@(" @("!\,3 O." @(" @(" @(" @( H@(" @('PQ,"XP+C N
M,"\S,B!\,3 N,"XP+C O,S(@('PQ,"XQ+C(N,R\X(" @(" @?#$P+S@@(" @
M(" @(" @(" *(" @("!\,3 N,2XR+C,O,S(@?#$P+C$N,BXS+S,R("!\,3 N
M,2XR+C,@(" @(" @('PQ,"XQ+C(N,R\S,B @(" @"B @(" @?#$P+C$N,B\R
M-" @('PQ,"XQ+C(O,C0@(" @?#$P+C$N,BXS+S(T(" @("!\,3 N,2XR+S(T
M(" @(" @( H@(" @('PQ,"XQ+S$V(" @("!\,3 N,2\Q-B @(" @('PQ,"XQ
M+C(N,R\Q-B @(" @?#$P+C$O,38@(" @(" @(" *(" @("!\,3 O." @(" @
M(" @?#$P+S@@(" @(" @("!\,3 N,2XR+C,O." @(" @('PQ,"\X(" @(" @
M(" @(" @"B@X(')O=W,I"@I1545263H@4T5,14-4("<G(&%S(&5I9VAT+"!C
M(&%S(&-I9'(L(&UA<VML96XH8RD@87,@(FUA<VML96XH8VED<BDB+ H@(&D@
M87,@:6YE="P@;6%S:VQE;BAI*2!A<R B;6%S:VQE;BAI;F5T*2(@1E)/32!)
M3D547U1"3#L*96EG:'1\8VED<B @(" @(" @?&UA<VML96XH8VED<BE\:6YE
M=" @(" @(" @(" @('QM87-K;&5N*&EN970I"BTM+2TM*RTM+2TM+2TM+2TM
M+2LM+2TM+2TM+2TM+2TM*RTM+2TM+2TM+2TM+2TM+2TK+2TM+2TM+2TM+2TM
M+0H@(" @('PQ.3(N,38X+C$O,C1\(" @(" @(" @(" R-'PQ.3(N,38X+C$N
M,C(V+S(T?" @(" @(" @(" @,C0*(" @("!\,3DR+C$V."XQ+S(T?" @(" @
M(" @(" @,C1\,3DR+C$V."XQ+C(R-B @('P@(" @(" @(" @(#,R"B @(" @
M?#$P+S@@(" @(" @('P@(" @(" @(" @(" X?#$P+C$N,BXS+S@@(" @("!\
M(" @(" @(" @(" @. H@(" @('PQ,"XP+C N,"\S,B!\(" @(" @(" @(" S
M,GPQ,"XQ+C(N,R\X(" @(" @?" @(" @(" @(" @(#@*(" @("!\,3 N,2XR
M+C,O,S(@?" @(" @(" @(" @,S)\,3 N,2XR+C,@(" @(" @('P@(" @(" @
M(" @(#,R"B @(" @?#$P+C$N,B\R-" @('P@(" @(" @(" @(#(T?#$P+C$N
M,BXS+S(T(" @("!\(" @(" @(" @(" R- H@(" @('PQ,"XQ+S$V(" @("!\
M(" @(" @(" @(" Q-GPQ,"XQ+C(N,R\Q-B @(" @?" @(" @(" @(" @,38*
M(" @("!\,3 O." @(" @(" @?" @(" @(" @(" @(#A\,3 N,2XR+C,O." @
M(" @('P@(" @(" @(" @(" X"B@X(')O=W,I"@I1545263H@4T5,14-4("<G
M(&%S('1W;RP@8R!A<R!C:61R+"!M87-K;&5N*&,I(&%S(")M87-K;&5N*&-I
M9'(I(BP*("!I(&%S(&EN970L(&UA<VML96XH:2D@87,@(FUA<VML96XH:6YE
M="DB($923TT@24Y%5%]40DP*("!72$5212!M87-K;&5N*&,I(#P](#@["G1W
M;WQC:61R?&UA<VML96XH8VED<BE\:6YE=" @(" @('QM87-K;&5N*&EN970I
M"BTM+2LM+2TM*RTM+2TM+2TM+2TM+2TK+2TM+2TM+2TM+2LM+2TM+2TM+2TM
M+2TM"B @('PQ,"\X?" @(" @(" @(" @(#A\,3 N,2XR+C,O.'P@(" @(" @
M(" @(" X"B @('PQ,"\X?" @(" @(" @(" @(#A\,3 N,2XR+C,O.'P@(" @
M(" @(" @(" X"B@R(')O=W,I"@I1545263H@4T5,14-4("<G(&%S('-I>"P@
M8R!A<R!C:61R+"!I(&%S(&EN970@1E)/32!)3D547U1"3 H@(%=(15)%(&,@
M/2!I.PIS:7A\8VED<B @(" @(" @?&EN970@(" @(" @(" @(" *+2TM*RTM
M+2TM+2TM+2TM+2LM+2TM+2TM+2TM+2TM+2TM"B @('PQ.3(N,38X+C$O,C1\
M,3DR+C$V."XQ+C(R-B\R- H@("!\,3 O." @(" @(" @?#$P+C$N,BXS+S@@
M(" @(" *(" @?#$P+C$N,BXS+S,R('PQ,"XQ+C(N,R @(" @(" @"B @('PQ
M,"XQ+C(O,C0@("!\,3 N,2XR+C,O,C0@(" @( H@("!\,3 N,2\Q-B @(" @
M?#$P+C$N,BXS+S$V(" @(" *(" @?#$P+S@@(" @(" @('PQ,"XQ+C(N,R\X
1(" @(" @"B@V(')O=W,I"@H*
`
end




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

* Re: [HACKERS] Bug in current network.c
@ 1998-10-29 13:15  D'Arcy J.M. Cain <[email protected]>
  parent: Andreas Zeugswetter <[email protected]>
  0 siblings, 1 reply; 814+ messages in thread

From: D'Arcy J.M. Cain @ 1998-10-29 13:15 UTC (permalink / raw)
  To: Andreas Zeugswetter <[email protected]>; +Cc: '[email protected]' <[email protected]>

Thus spake Andreas Zeugswetter
> a - 1506-068 (S) Operation between types "char*" and "int" is not allowed.
> gmake[3]: *** [network.o] Error 1
> 
> It should probably read as follows: (but please check)
> (I sure hope it comes without those stupid wraps my mailer always 
> generates)

For some reason network.c reverted to an earlier version in the tree.  Your
patch was already submitted by someone (Bruce?) but the changes, like my
other changes, were lost.  I assume that your patch is correct but the
person who submitted the previous patch should double check that nothing
else is missing.

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.



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

* Re: [HACKERS] Bug in current network.c
@ 1998-10-29 16:16  Tom Lane <[email protected]>
  parent: D'Arcy J.M. Cain <[email protected]>
  0 siblings, 1 reply; 814+ messages in thread

From: Tom Lane @ 1998-10-29 16:16 UTC (permalink / raw)
  To: D'Arcy J.M. Cain <[email protected]>; +Cc: '[email protected]' <[email protected]>

[email protected] (D'Arcy J.M. Cain) writes:
> For some reason network.c reverted to an earlier version in the tree.  Your
> patch was already submitted by someone (Bruce?) but the changes, like my
> other changes, were lost.

It looks like Bruce copied-and-pasted a little too much while applying
your last patch.  I had fixed the "< 0" tests that ought to be "== NULL"
on Sunday, but one of them was on a line that you wanted changed for other
reasons, and it went back to being wrong...

Fixed now.

			regards, tom lane



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

* Re: [HACKERS] Bug in current network.c
@ 1998-10-29 17:59  D'Arcy J.M. Cain <[email protected]>
  parent: Tom Lane <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: D'Arcy J.M. Cain @ 1998-10-29 17:59 UTC (permalink / raw)
  To: Tom Lane <[email protected]>; +Cc: '[email protected]' <[email protected]>

Thus spake Tom Lane
> [email protected] (D'Arcy J.M. Cain) writes:
> > For some reason network.c reverted to an earlier version in the tree.  Your
> > patch was already submitted by someone (Bruce?) but the changes, like my
> > other changes, were lost.
> 
> It looks like Bruce copied-and-pasted a little too much while applying
> your last patch.  I had fixed the "< 0" tests that ought to be "== NULL"
> on Sunday, but one of them was on a line that you wanted changed for other
> reasons, and it went back to being wrong...

Trust us.  We're professionals.  :-)

-- 
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 424 2871     (DoD#0082)    (eNTP)   |  what's for dinner.



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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 814+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 814+ messages in thread


end of thread, other threads:[~2025-09-04 16:28 UTC | newest]

Thread overview: 814+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
1998-10-29 10:09 Bug in current network.c Andreas Zeugswetter <[email protected]>
1998-10-29 13:15 ` D'Arcy J.M. Cain <[email protected]>
1998-10-29 16:16   ` Tom Lane <[email protected]>
1998-10-29 17:59     ` D'Arcy J.M. Cain <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 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 v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox